package config

import (
	"common"
	"encoding/json"
	"gateway/core"
	"gateway/protocol/grpc"
	"gateway/protocol/http"
	"log"
	"os"
	"sync"
)

type RouteConfig struct {
	Path     string `json:"path"`
	Method   string `json:"method"`
	Target   string `json:"target"`
	Protocol string `json:"protocol"`
}

var (
	routes []RouteConfig
	mu     sync.RWMutex
)

func LoadFromFile(filename string) error {
	data, err := os.ReadFile(filename)
	if err != nil {
		return err
	}

	var newRoutes []RouteConfig
	if err := json.Unmarshal(data, &newRoutes); err != nil {
		return err
	}

	mu.Lock()
	routes = newRoutes
	mu.Unlock()
	return nil
}

func GetRoutes() []RouteConfig {
	mu.RLock()
	defer mu.RUnlock()
	return routes
}

func ApplyRoutes(g *core.Gateway) {
	for _, route := range GetRoutes() {

		switch route.Protocol {
		//GRPC 路由处理
		case "grpc":
			handler := &grpc.GRPCProxy{
				Service: route.Target,
				Method:  route.Path,
			}
			g.Router.AddRoute(route.Method, route.Path, handler.Handle)
			// HTTP 反向代理路由处理
		case "http":
			ip, port := common.GetEtcdServer(route.Target)
			address := getAddress(ip, port)
			route.Target = address
			proxy, err := http.NewReverseProxy(route.Target)
			if err != nil {
				log.Printf("Failed to create proxy: %v", err)
				continue
			}
			g.Router.AddRoute(route.Method, route.Path, proxy.Handle)
		}
	}
}

func getAddress(ip, port string) string {
	return "http://" + ip + ":" + port
}
